<template>
  <div class="flex flex-col">
    <!-- 搜索和筛选区域 -->
    <div class="flex justify-between">
      <el-form :model="searchForm" inline label-width="80px">
        <el-form-item label="文件名">
          <el-input
            v-model="searchForm.filename"
            placeholder="请输入文件名"
            clearable
            class="w-48"
          />
        </el-form-item>
        <el-form-item label="类别">
          <el-select v-model="searchForm.category" placeholder="请选择类别" clearable class="w-48">
            <el-option v-for="cat in categories" :key="cat" :label="cat" :value="cat" />
          </el-select>
        </el-form-item>
        <el-form-item label="文件类型">
          <el-input
            v-model="searchForm.imageType"
            placeholder="请输入文件类型"
            clearable
            class="w-32"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleSearch">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
        </el-form-item>
      </el-form>
      <div>
        <el-button type="danger" @click="handleBatchDelete" :disabled="selectedIds.length === 0">
          批量删除
        </el-button>
        <el-button type="primary" @click="handleUpload" :icon="Upload"> 上传文件 </el-button>
      </div>
    </div>

    <!-- 附件列表 -->
    <div class="flex h-0 grow flex-col">
      <el-table
        class="grow"
        v-loading="loading"
        :data="attachmentList.list"
        border
        stripe
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column prop="id" label="ID" width="80" />
        <el-table-column label="类别" width="120">
          <template #default="scope">
            <el-tag size="small">{{ scope.row.category }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="预览">
          <template #default="scope">
            <div class="flex justify-center">
              <el-image
                v-if="isImage(scope.row.imageType)"
                :src="baseUrl + scope.row.url"
                :preview-src-list="[baseUrl + scope.row.url]"
                fit="cover"
                class="max-h-48 w-48"
              />
              <div v-else class="flex h-12 w-12 items-center justify-center rounded bg-gray-100">
                <i :class="getFileIcon(scope.row.imageType)" class="text-3xl"></i>
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="文件名" width="200" show-overflow-tooltip>
          <template #default="scope">
            <el-link :href="scope.row.url" target="_blank" type="primary">
              {{ scope.row.filename }}
            </el-link>
          </template>
        </el-table-column>
        <el-table-column label="文件大小" width="100">
          <template #default="scope">
            {{ formatFileSize(scope.row.filesize) }}
          </template>
        </el-table-column>
        <el-table-column prop="imageWidth" label="宽度" width="80" />
        <el-table-column prop="imageHeight" label="高度" width="80" />
        <el-table-column prop="imageType" label="文件类型" width="100" />
        <el-table-column prop="storage" label="存储引擎" width="100" />
        <el-table-column prop="mimetype" label="Mime类型" width="200" show-overflow-tooltip />
        <el-table-column prop="uploadTime" label="上传时间" show-overflow-tooltip />
        <el-table-column label="操作" width="200" fixed="right">
          <template #default="scope">
            <el-button type="primary" link @click="handleEdit(scope.row)"> 编辑 </el-button>
            <el-button type="danger" link @click="handleDelete(scope.row)"> 删除 </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="mt-2 flex justify-end">
        <el-pagination
          v-model:current-page="searchForm.page"
          v-model:page-size="searchForm.pageSize"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="attachmentList.total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>

    <!-- 上传对话框 -->
    <el-dialog v-model="uploadDialogVisible" title="上传文件" width="600px" destroy-on-close>
      <el-form :model="uploadForm" label-width="120px">
        <el-form-item label="上传到本地">
          <el-upload
            ref="uploadRef"
            :auto-upload="false"
            :on-change="handleFileChange"
            :limit="1"
            :file-list="fileList"
          >
            <el-button type="primary" :icon="Upload">选择文件</el-button>
          </el-upload>
        </el-form-item>
        <el-form-item label="类别">
          <el-select
            v-model="uploadForm.category"
            placeholder="请选择类别"
            clearable
            allow-create
            filterable
            class="w-full"
          >
            <el-option v-for="cat in categories" :key="cat" :label="cat" :value="cat" />
          </el-select>
        </el-form-item>
        <el-form-item label="透传数据">
          <el-input
            v-model="uploadForm.extparam"
            placeholder="请输入透传数据"
            type="textarea"
            :rows="3"
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="flex justify-end space-x-2">
          <el-button @click="uploadDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmUpload" :loading="uploading">
            确认上传
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 编辑对话框 -->
    <el-dialog v-model="editDialogVisible" title="编辑附件" width="700px" destroy-on-close>
      <el-form :model="editForm" label-width="120px" v-loading="loadingDetail">
        <el-form-item label="类别">
          <el-select
            v-model="editForm.category"
            placeholder="请选择类别"
            clearable
            allow-create
            filterable
            class="w-full"
          >
            <el-option v-for="cat in categories" :key="cat" :label="cat" :value="cat" />
          </el-select>
        </el-form-item>
        <el-form-item label="物理路径">
          <el-input v-model="editForm.url" placeholder="请输入物理路径" />
        </el-form-item>
        <el-form-item label="宽度">
          <el-input-number
            controls-position="right"
            v-model="editForm.imageWidth"
            :min="0"
            class="w-full"
          />
        </el-form-item>
        <el-form-item label="高度">
          <el-input-number
            controls-position="right"
            v-model="editForm.imageHeight"
            :min="0"
            class="w-full"
          />
        </el-form-item>
        <el-form-item label="图片类型">
          <el-input v-model="editForm.imageType" placeholder="请输入图片类型" />
        </el-form-item>
        <el-form-item label="图片帧数">
          <el-input-number
            controls-position="right"
            v-model="editForm.imageFrames"
            :min="0"
            class="w-full"
          />
        </el-form-item>
        <el-form-item label="文件名">
          <el-input v-model="editForm.filename" placeholder="请输入文件名" />
        </el-form-item>
        <el-form-item label="文件大小">
          <el-input-number
            controls-position="right"
            v-model="editForm.filesize"
            :min="0"
            class="w-full"
          />
        </el-form-item>
        <el-form-item label="Mime类型">
          <el-input v-model="editForm.mimetype" placeholder="请输入Mime类型" />
        </el-form-item>
        <el-form-item label="透传数据">
          <el-input
            v-model="editForm.extparam"
            placeholder="请输入透传数据"
            type="textarea"
            :rows="2"
          />
        </el-form-item>
        <el-form-item label="存储引擎">
          <el-select v-model="editForm.storage" placeholder="请选择存储引擎" class="w-full">
            <el-option
              v-for="engine in storageEngines"
              :key="engine"
              :label="engine"
              :value="engine"
            />
          </el-select>
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="flex justify-end space-x-2">
          <el-button @click="editDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="confirmEdit" :loading="loadingSave"> 保存 </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import {
  batchDeleteAttachments,
  deleteAttachment,
  getAttachment,
  getAttachmentList,
  getCategories,
  getStorageEngines,
  updateAttachment,
  uploadFile
} from '@/api/system/attachment'
import { to } from '@/utils/promise'
import { Upload } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox, type UploadInstance, type UploadUserFile } from 'element-plus'
import { onMounted, reactive, ref } from 'vue'
const baseUrl = import.meta.env.VITE_API_FIRE_URL
// 搜索表单
const searchForm = reactive<AttachmentQueryParams>({
  page: 1,
  pageSize: 10,
  category: '',
  filename: '',
  imageType: ''
})

// 附件列表
const attachmentList = reactive<{
  list: Attachment[]
  total: number
}>({
  list: [],
  total: 0
})

const loading = ref(false)
const selectedIds = ref<number[]>([])
const categories = ref<string[]>([])
const storageEngines = ref<string[]>([])

// 上传相关
const uploadDialogVisible = ref(false)
const uploadRef = ref<UploadInstance>()
const fileList = ref<UploadUserFile[]>([])
const uploading = ref(false)
const uploadForm = reactive({
  category: '',
  extparam: ''
})
const currentFile = ref<File | null>(null)

// 编辑相关
const editDialogVisible = ref(false)
const loadingDetail = ref(false)
const loadingSave = ref(false)
const currentEditId = ref<number>(0)
const editForm = reactive<AttachmentUpdateRequest>({
  category: '',
  url: '',
  imageWidth: 0,
  imageHeight: 0,
  imageType: '',
  imageFrames: 0,
  filename: '',
  filesize: 0,
  mimetype: '',
  extparam: '',
  storage: ''
})

// 获取附件列表
const fetchAttachmentList = async () => {
  loading.value = true
  const [error, result] = await to(getAttachmentList(searchForm))
  if (error) {
    console.error('获取附件列表失败:', error)
    return
  }
  attachmentList.list = result.list || []
  attachmentList.total = result.total || 0
  loading.value = false
  return result
}

// 获取类别列表
const fetchCategories = async () => {
  const [error, result] = await to(getCategories())
  if (error) {
    console.error('获取类别列表失败:', error)
    return
  }
  categories.value = result || []
}

// 获取存储引擎列表
const fetchStorageEngines = async () => {
  const [error, result] = await to(getStorageEngines())
  if (error) {
    console.error('获取存储引擎列表失败:', error)
    return
  }
  storageEngines.value = result || []
}

// 搜索
const handleSearch = () => {
  searchForm.page = 1
  fetchAttachmentList()
}

// 重置搜索
const resetSearch = () => {
  searchForm.page = 1
  searchForm.pageSize = 10
  searchForm.category = ''
  searchForm.filename = ''
  searchForm.imageType = ''
  fetchAttachmentList()
}

// 选择变化
const handleSelectionChange = (selection: Attachment[]) => {
  selectedIds.value = selection.map((item) => item.id)
}

// 分页变化
const handleSizeChange = (pageSize: number) => {
  searchForm.pageSize = pageSize
  searchForm.page = 1
  fetchAttachmentList()
}

const handleCurrentChange = (page: number) => {
  searchForm.page = page
  fetchAttachmentList()
}

// 上传文件
const handleUpload = () => {
  uploadForm.category = ''
  uploadForm.extparam = ''
  fileList.value = []
  currentFile.value = null
  uploadDialogVisible.value = true
}

// 文件变化
const handleFileChange = (file: any) => {
  currentFile.value = file.raw
}

// 确认上传
const confirmUpload = async () => {
  if (!currentFile.value) {
    ElMessage.warning('请选择要上传的文件')
    return
  }

  uploading.value = true
  const [error, result] = await to(
    uploadFile(currentFile.value, uploadForm.category, uploadForm.extparam)
  )
  if (error) {
    ElMessage.error('上传失败')
    uploading.value = false
    return
  }
  ElMessage.success('上传成功')
  uploadDialogVisible.value = false
  fetchAttachmentList()
  fetchCategories()
  uploading.value = false
  return result
}

// 编辑
const handleEdit = async (row: Attachment) => {
  currentEditId.value = row.id
  loadingDetail.value = true
  editDialogVisible.value = true

  const [error, data] = await to(getAttachment(row.id))
  if (error) {
    console.error('获取附件详情失败:', error)
    loadingDetail.value = false
    return
  }

  editForm.category = data.category
  editForm.url = data.url
  editForm.imageWidth = data.imageWidth
  editForm.imageHeight = data.imageHeight
  editForm.imageType = data.imageType
  editForm.imageFrames = data.imageFrames
  editForm.filename = data.filename
  editForm.filesize = data.filesize
  editForm.mimetype = data.mimetype
  editForm.extparam = data.extparam
  editForm.storage = data.storage
  loadingDetail.value = false
}

// 确认编辑
const confirmEdit = async () => {
  loadingSave.value = true
  const [error] = await to(updateAttachment(currentEditId.value, editForm))
  if (error) {
    console.error('更新失败:', error)
    ElMessage.error('更新失败')
    loadingSave.value = false
    return
  }
  ElMessage.success('更新成功')
  editDialogVisible.value = false
  loadingSave.value = false
  fetchAttachmentList()
}

// 删除
const handleDelete = async (row: Attachment) => {
  try {
    await ElMessageBox.confirm('确定要删除这个附件吗？', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })

    const [error] = await to(deleteAttachment(row.id))
    if (error) {
      console.error('删除失败:', error)
      ElMessage.error('删除失败')
      return
    }
    ElMessage.success('删除成功')
    fetchAttachmentList()
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('删除失败:', error)
    }
  }
}

// 批量删除
const handleBatchDelete = async () => {
  if (selectedIds.value.length === 0) {
    ElMessage.warning('请选择要删除的附件')
    return
  }

  try {
    await ElMessageBox.confirm(`确定要删除选中的 ${selectedIds.value.length} 个附件吗？`, '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })

    const [error] = await to(batchDeleteAttachments(selectedIds.value))
    if (error) {
      console.error('批量删除失败:', error)
      ElMessage.error('批量删除失败')
      return
    }
    ElMessage.success('批量删除成功')
    fetchAttachmentList()
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('批量删除失败:', error)
    }
  }
}

// 判断是否是图片
const isImage = (type: string) => {
  const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg']
  return imageTypes.includes(type?.toLowerCase())
}

// 获取文件图标
const getFileIcon = (type: string) => {
  const iconMap: Record<string, string> = {
    pdf: 'el-icon-document',
    doc: 'el-icon-document',
    docx: 'el-icon-document',
    xls: 'el-icon-document',
    xlsx: 'el-icon-document',
    ppt: 'el-icon-document',
    pptx: 'el-icon-document',
    txt: 'el-icon-document',
    zip: 'el-icon-folder',
    rar: 'el-icon-folder',
    mp4: 'el-icon-video-camera',
    avi: 'el-icon-video-camera',
    mp3: 'el-icon-headset',
    wav: 'el-icon-headset'
  }
  return iconMap[type?.toLowerCase()] || 'el-icon-document'
}

// 格式化文件大小
const formatFileSize = (size: number) => {
  if (!size) return '0 B'
  const units = ['B', 'KB', 'MB', 'GB', 'TB']
  let index = 0
  let fileSize = size
  while (fileSize >= 1024 && index < units.length - 1) {
    fileSize /= 1024
    index++
  }
  return `${fileSize.toFixed(2)} ${units[index]}`
}

onMounted(() => {
  fetchAttachmentList()
  fetchCategories()
  fetchStorageEngines()
})
</script>

<style scoped></style>
